package edu.ntu.cloudroid.model.function.similar;

import edu.ntu.cloudroid.model.data.LocationData;
import edu.ntu.cloudroid.model.data.LocationInfo;

public class LocationSimilar implements ISimilarFunc{

	private static final double EARTH_RADIUS = 6371.0;
	
	@Override
	public boolean isSimilar(Object object1, Object object2, int colIdx,
			int granularity, double range) throws Exception{
		//if granularity = 0, object 1 and 2 must be in the given range
		LocationData ld1 = (LocationData)object1;
		LocationData ld2 = (LocationData)object2;
		
		if (granularity==0){
			return isWithinRadius(ld1.getLongitude(), ld1.getLatitude(),
					ld2.getLongitude(), ld2.getLatitude(), range);
		}
		LocationInfo lo1 = (LocationInfo)ld1.changeGranuality(granularity, colIdx);
		LocationInfo lo2 = (LocationInfo)ld2.changeGranuality(granularity, colIdx);		
		return lo1.getLocationName().equals(lo2.getLocationName());
	}

	private boolean isWithinRadius(double lo1, double la1, double lo2, double la2, double range ){
		double dLat = Math.toRadians((la1 - la2));
        double dLong = Math
              .toRadians((lo1 - lo2));
        double targetLatitudeRad = Math.toRadians(la2);
        double subjectLatitudeRad = Math.toRadians(la1);

        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
              + Math.sin(dLong / 2) * Math.sin(dLong / 2)
              * Math.cos(targetLatitudeRad) * Math.cos(subjectLatitudeRad);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        double d = EARTH_RADIUS * c;

        return d<=range;        
	}
}
